using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Component.Interop;
using System.IO;
using BizExcel.Libary;
using Microsoft.BizTalk.Message.Interop;
using System.ComponentModel;
using System.Resources;
using System.Collections;
using System.Drawing;
using System.Reflection;

namespace BizExcel.PipelineComponents
{
    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
    [ComponentCategory(CategoryTypes.CATID_Decoder)]
    [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
    [System.Runtime.InteropServices.Guid("0a37004e-4e95-48e3-ac30-a0cf40fe51ec")]
    public class ExcelDisassemble : IBaseComponent,
        Microsoft.BizTalk.Component.Interop.IComponent,
        Microsoft.BizTalk.Component.Interop.IPersistPropertyBag,
        IComponentUI
    {
        private ResourceManager resourceManager = new ResourceManager("BizExcel.PipelineComponents.Resource", Assembly.GetExecutingAssembly());
        #region Properties
        private string _tempFolderPath = null;
        public string TempFolderPath
        {
            get
            {
                return _tempFolderPath;
            }
            set
            {
                _tempFolderPath = value;
            }
        }
        #endregion

        #region IBaseComponent

        /// <summary>
        /// Name of the component.
        /// </summary>
        [Browsable(false)]
        public string Name
        {
            get { return "BizExcel Decoder"; }
        }

        /// <summary>
        /// Version of the component.
        /// </summary>
        [Browsable(false)]
        public string Version
        {
            get { return "0.0.1.0"; }
        }

        /// <summary>
        /// Description of the component.
        /// </summary>
        [Browsable(false)]
        public string Description
        {
            get { return "Convert Excel to XML by customer map"; }
        }
        #endregion

        #region IComponent
        public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            #region Argument Check
            if (null == _tempFolderPath)
            {
                throw new ArgumentNullException("TempFolderPath");
            }
            #endregion
            IBaseMessage disassembledMessage = null;
            Stream originalStrm = null;
            try
            {
                disassembledMessage = inmsg;
                originalStrm = inmsg.BodyPart.GetOriginalDataStream();
                disassembledMessage.BodyPart.Data = ExcelConvert.ExcelStreamToXML(_tempFolderPath, originalStrm);
                return disassembledMessage;
            }
            catch (Exception exp)
            {
                throw exp;
            }
            finally
            {
                if (null != disassembledMessage)
                {
                    disassembledMessage = null;
                }
                if (null != originalStrm)
                {
                    originalStrm = null;
                }
            }
        }
        #endregion

        #region Config
        //IPersistPropertyBag Members
        /// <summary>
        /// Gets class ID of component for usage from unmanaged code.
        /// </summary>
        /// <param name="classid">
        /// Class ID of the component
        /// </param>
        public void GetClassID(out System.Guid classID)
        {
            classID = new System.Guid("c5e417a6-19bb-4199-97f3-cc161ef4945f");
        }

        /// <summary>
        /// not implemented
        /// </summary>
        public void InitNew()
        {
        }

        /// <summary>
        /// Loads configuration properties for the component
        /// </summary>
        /// <param name="pb">Configuration property bag</param>
        /// <param name="errlog">Error status</param>
        public void Load(IPropertyBag propertyBag, int errorLog)
        {
            object val = null;

            val = ReadPropertyBag(propertyBag, "TempFolderPath");

            if ((val != null))
            {
                this._tempFolderPath = ((string)val);
            }
        }

        /// <summary>
        /// Saves the current component configuration into the property bag
        /// </summary>
        /// <param name="pb">Configuration property bag</param>
        /// <param name="fClearDirty">not used</param>
        /// <param name="fSaveAllProperties">not used</param>
        public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
        {
            WritePropertyBag(propertyBag, "TempFolderPath", this.TempFolderPath);
        }

        /// <summary>
        /// Reads property value from property bag
        /// </summary>
        /// <param name="pb">Property bag</param>
        /// <param name="propName">Name of property</param>
        /// <returns>Value of the property</returns>
        private static object ReadPropertyBag(IPropertyBag propertyBag, string propName)
        {
            object val = null;
            try
            {
                propertyBag.Read(propName, out val, 0);
            }
            catch (System.ArgumentException)
            {
                return val;
            }
            catch (System.Exception e)
            {
                throw e;
            }
            return val;
        }

        /// <summary>
        /// Writes property values into a property bag.
        /// </summary>
        /// <param name="pb">Property bag.</param>
        /// <param name="propName">Name of property.</param>
        /// <param name="val">Value of property.</param>
        private static void WritePropertyBag(IPropertyBag propertyBag, string propName, object val)
        {
            try
            {
                propertyBag.Write(propName, ref val);
            }
            catch (System.Exception e)
            {
                throw e;
            }
        }
        #endregion

        #region IComponentUI Members
        /// <summary>
        /// Sets the icon in the BizTalk toolbar
        /// </summary>
        [Browsable(false)]
        IntPtr IComponentUI.Icon
        {
            get
            {
                return ((Bitmap)(this.resourceManager.GetObject("BIZEXCEL", System.Globalization.CultureInfo.InvariantCulture))).GetHicon();
            }
        }

        /// <summary>
        /// The Validate method is called by the BizTalk Editor during the build 
        /// of a BizTalk project.
        /// </summary>
        /// <param name="obj">An Object containing the configuration properties.</param>
        /// <returns>The IEnumerator enables the caller to enumerate through a collection of strings containing error messages. These error messages appear as compiler error messages. To report successful property validation, the method should return an empty enumerator.</returns>
        IEnumerator IComponentUI.Validate(object projectSystem)
        {
            // Nothing to validate, always returns success
            return new ArrayList(0).GetEnumerator();
        }

        #endregion
    }
}
